/*
 * Filename: server_tcp_epoll.c
 * Description: TODO: Add description
 *
 * Created: 2025-05-29
 * Author: lyh
 */

#include <my_header.h>

void quit(int *fd, int *epfd);

int main(int argc, char *argv[]) {
	// ./server_tcp_epoll 192.168.48.128 12345
	ARGS_CHECK(argc, 3);
	// 准备地址
	struct sockaddr_in server_addr;
	server_addr.sin_family = AF_INET;
	server_addr.sin_addr.s_addr = inet_addr(argv[1]);
	server_addr.sin_port = htons(atoi(argv[2]));
	// 初始socket,绑定服务端端口
	int server_fd = socket(AF_INET, SOCK_STREAM, 0);
	ERROR_CHECK(server_fd, -1, "socket error");

	int tag = connect(server_fd, (struct sockaddr *)&server_addr,
					  sizeof(server_addr));
	ERROR_CHECK(tag, -1, "connect error");
	// 设置epoll监听集合 fd epoll_event;
	int epfd = epoll_create(1);
	struct epoll_event add_fd_events, ready_fd_events;
	add_fd_events.data.fd = server_fd;
	add_fd_events.events = EPOLLIN;
	tag = epoll_ctl(epfd, EPOLL_CTL_ADD, server_fd, &add_fd_events);
	ERROR_CHECK(tag, -1, "epoll_ctl error");

	add_fd_events.data.fd = STDIN_FILENO;
	tag = epoll_ctl(epfd, EPOLL_CTL_ADD, STDIN_FILENO, &add_fd_events);
	ERROR_CHECK(tag, -1, "epoll_ctl error");

	// 用户先关数据
	char buffer[4096];
	while (1) {

		int maxcount = epoll_wait(epfd, &ready_fd_events, 1, -1);
		ERROR_CHECK(maxcount, -1, "epoll_wat error");
		ERROR_CHECK(maxcount, 0, "epoll_wait interrupt");
        bzero(buffer,4096);
        if(ready_fd_events.data.fd==server_fd)
        {
            int read_cout =recv(server_fd,buffer,4096,0);
            ERROR_CHECK(read_cout,-1,"recv error");
            if(read_cout==0)
                break;
            printf("server %d:%s\n",server_fd,buffer);
        }else{
            int read_cout =read(STDIN_FILENO,buffer,4096);
            int cout=send(server_fd,buffer,read_cout,0);
				if (cout == -1) {
					perror("send error");
					quit(&server_fd, &epfd);
                    break;
				}
        }
	}
    printf("client exit\n");
    quit(&server_fd,&epfd);
    close(epfd);
	return 0;
}

void quit(int *fd, int *epfd) {
	if (*fd != -1) {
		epoll_ctl(*epfd, EPOLL_CTL_DEL, *fd, NULL);
		close(*fd);
		*fd = -1;
	}
}
